<template>
  <div>
    <el-form
      ref="formRef"
      :model="spuInfo"
      :rules="rules"
      label-width="120px"
      action="/"
      @submit.prevent
    >
      <el-form-item label="SPU名称" prop="spuName">
        <el-input placeholder="SPU名称" v-model="spuInfo.spuName"></el-input>
      </el-form-item>
      <el-form-item label="品牌" prop="tmId">
        <el-select v-model="spuInfo.tmId">
          <el-option
            v-for="tm in trademarkList"
            :key="tm.id"
            :label="tm.tmName"
            :value="tm.id || 0"
          ></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="SPU描述" prop="description">
        <el-input
          type="textarea"
          placeholder="SPU描述"
          rows="4"
          v-model="spuInfo.description"
        ></el-input>
      </el-form-item>

      <el-form-item label="SPU图片" prop="spuImageList">
        <el-upload
          multiple
          :file-list="(spuInfo.spuImageList as any)"
          :action="`${BASE_URL}/admin/product/fileUpload`"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-success="handleSuccess"
          :on-remove="handleRemove"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>
        <el-dialog v-model="dialogVisible">
          <img w-full :src="dialogImageUrl" alt="" />
        </el-dialog>
      </el-form-item>

      <el-form-item label="销售属性" prop="spuSaleAttrList">
        <el-select v-model="saleAttrIdName" :placeholder="saleListText">
          <el-option
            v-for="item in unUseSaleAttrList"
            :key="item.id"
            :label="item.name"
            :value="item.id + ':' + item.name"
          ></el-option>
        </el-select>
        <div>
          <el-button type="primary" :icon="Plus" @click="addSpuSaleAttr">
            添加销售属性
          </el-button>
        </div>

        <div>
          <vxe-table
            style="margin: 20px 0"
            :data="spuInfo?.spuSaleAttrList"
            border
          >
            <vxe-column
              title="序号"
              type="seq"
              status="index"
              width="80"
              align="center"
            >
            </vxe-column>
            <vxe-column title="属性名" field="saleAttrName" width="150">
            </vxe-column>
            <vxe-column title="属性值名称列表" width="200">
              <template #default="{ row, $rowindex }">
                <el-tag
                  closable
                  :disable-transitions="false"
                  @close="row.spuSaleAttrValueList.splice($rowindex, 1)"
                  style="margin-right: 5px"
                  v-for="(item, $rowindex) in row.spuSaleAttrValueList"
                  :key="item.saleAttrValueName"
                  type="success"
                  >{{ item.saleAttrValueName }}
                </el-tag>

                <el-input
                  v-model="saleAttrValueName"
                  v-if="row.isShowEdit"
                  @blur="toView(row)"
                  :ref="(input: any) => {inputsRef[$rowindex] = input}"
                  placeholder="名称"
                  size="small"
                  style="width: 100px"
                />
                <el-button
                  @click="toEdit(row, $rowindex)"
                  v-else
                  size="small"
                  :icon="Plus"
                ></el-button>
              </template>
            </vxe-column>
            <vxe-column title="操作" width="150">
              <template v-slot="{ $index }">
                <el-button
                  @click="spuInfo?.spuSaleAttrList.splice($index, 1)"
                  title="删除"
                  type="danger"
                  size="small"
                  :icon="Delete"
                ></el-button>
              </template>
            </vxe-column>
          </vxe-table>
        </div>
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="save">保存</el-button>
        <el-button @click="emits('setShowStatus', ShowStatus.SPU_LIST)">
          取消
        </el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script lang="ts">
export default {
  name: "SpuForm",
};
</script>

<script lang="ts" setup>
import { ref, reactive, onMounted, computed, nextTick } from "vue";
import type {
  BaseSaleAttrListModel,
  SpuModel,
  SpuSaleAttrModel,
  TrademarkListModel,
} from "@/types";
import {
  getSpuImageListApi,
  getBaseSaleAttrListApi,
  getSpuSaleAttrListApi,
  addOrUpdateSpuApi,
} from "@/api/product/spu";
import { getAllTrademarkListApi } from "@/api/product/trademark";
import { Plus, Delete } from "@element-plus/icons-vue";
import { ShowStatus } from "../types";
import type {
  FormInstance,
  FormRules,
  UploadFile,
  UploadFiles,
} from "element-plus";
import { ElMessage } from "element-plus";
import { useCategoryStore } from "@/stores/category";
const categoryStore = useCategoryStore();
const emits = defineEmits(["setShowStatus"]);

// 接收到的SPU数据
const props = defineProps<{
  currentSpu: SpuModel;
}>();

const spuInfo = reactive<SpuModel>(props.currentSpu); // 当前SPU信息
const trademarkList = ref<TrademarkListModel>([]); // 品牌列表
const baseSaleAttrList = ref<BaseSaleAttrListModel>([]); // 基础销售属性列表

// 生命周期可以写多个
onMounted(async () => {
  // 获取基础销售属性列表
  baseSaleAttrList.value = await getBaseSaleAttrListApi();
});
onMounted(async () => {
  // 获取所有品牌列表
  trademarkList.value = await getAllTrademarkListApi();
});
onMounted(async () => {
  // 如果spuInfo有id, 获取图片列表
  const id = spuInfo.id as number;
  if (!id) return;
  const spuImageList = await getSpuImageListApi(id);
  spuInfo.spuImageList = spuImageList.map((item) => ({
    ...item,
    name: item.imgName,
    url: item.imgUrl,
  }));
});
onMounted(async () => {
  // 如果spuInfo有id, 获取spu销售属性列表
  const id = spuInfo.id as number;
  if (!id) return;
  spuInfo.spuSaleAttrList = await getSpuSaleAttrListApi(id);
});

// 上传图片地址：从.env.development中加载的
const BASE_URL = import.meta.env.VITE_API_URL;
const dialogImageUrl = ref("");
const dialogVisible = ref(false);

/**
 * 点击放大镜图标的回调
 * @param file
 */
const handlePictureCardPreview = (file: UploadFile) => {
  console.log(file);

  // 保存预览的图片url
  dialogImageUrl.value = file.url as string;
  // 显示dialog
  dialogVisible.value = true;
};
/*
  上传图片成功的回调
  response: 响应体对象
  file: 上传成功的文件对象
  fileList: 所有已上传的文件对象的数组
  */
const handleSuccess = (
  response: any,
  file: UploadFile,
  fileList: UploadFiles
) => {
  console.log("handleSuccess", fileList);
  spuInfo.spuImageList = fileList as any;
};

/*
  删除图的回调
  file: 删除文件对象
  fileList: 剩下的已上传的文件对象的数组
  */
const handleRemove = (file: UploadFile, fileList: UploadFiles) => {
  spuInfo.spuImageList = fileList as any;
};

const saleAttrIdName = ref(""); // 用于收集选择的销售属性   id:name
const saleAttrValueName = ref<string>(""); // 收集用户输入的销售属性值名称
const inputsRef = ref<HTMLInputElement[]>([]);

/*
  用于显示下拉列表的未使用的销售属性列表
  */
const unUseSaleAttrList = computed(() => {
  // 计算产生一个要用的数据, 并返回
  // 过滤总销售属性列表
  return baseSaleAttrList.value.filter((attr) => {
    // 看attr.name有没有在spuSaleAttrList中一个对应的   name===saleAttrName
    // 如果没有, 才留下来
    return !spuInfo.spuSaleAttrList.some(
      (item) => item.saleAttrName == attr.name
    );
    // return spuInfo.value?.spuSaleAttrList.every(item => item.saleAttrName!=attr.name)
  });
});

/*
  销售属性下拉列表的文本提示
  */
const saleListText = computed(() => {
  const { length } = unUseSaleAttrList.value;
  return length > 0 ? `还有${length}未选择` : "没有啦!";
});

/**
 * 添加spu销售属性
 */
const addSpuSaleAttr = () => {
  const [id, name] = saleAttrIdName.value.split(":");
  if (id) {
    /*
    向spuInfo.spuSaleAttrList中添加一个属性对象:
      {
          "baseSaleAttrId": "1", // 销售属性id
          "saleAttrName": "选择颜色",  // 销售属性名
          "spuSaleAttrValueList": []
        }
    */
    spuInfo.spuSaleAttrList.push({
      baseSaleAttrId: +id, // 销售属性id
      saleAttrName: name, // 销售属性名
      spuSaleAttrValueList: [],
    });
    // 清除收集的数据
    saleAttrIdName.value = "";
  }
};

/**
 * 变为查看模式
 * @param saleAttr
 */
const toView = (saleAttr: SpuSaleAttrModel) => {
  if (saleAttrValueName.value) {
    // 添加
    saleAttr.spuSaleAttrValueList.push({
      baseSaleAttrId: saleAttr.baseSaleAttrId,
      saleAttrValueName: saleAttrValueName.value,
    });
    // 清空
    saleAttrValueName.value = "";
  }
  // 变成显示模式
  saleAttr.isShowEdit = false;
};

/**
 * 变为编辑模式
 * @param row
 * @param index
 *
 */
const toEdit = (row: SpuSaleAttrModel, index: number) => {
  // 显示Input
  row.isShowEdit = true;
  // 在input自动获取焦点
  nextTick(() => {
    inputsRef.value[index].focus();
  });
};

const formRef = ref<FormInstance>();

// 表单验证规则
const rules: FormRules = {
  spuName: [{ required: true, message: "请输入SPU名称", trigger: "blur" }],
  tmId: [{ required: true, message: "请选择SPU品牌" }],
  description: [{ required: true, message: "请输入SPU描述", trigger: "blur" }],
  spuImageList: [{ required: true, message: "请上传SPU图片", type: "array" }],
  spuSaleAttrList: [
    { required: true, message: "请添加SPU销售属性", type: "array" },
  ],
};

/*
  添加或者更新spuInfo
  */
const save = async () => {
  // 进行表单校验, 如果通过返回成功的promise
  await formRef.value?.validate();

  // 整理1: spuImageList
  /*
      从后台获取的图片文件对象的结构
			{
			    "id": 333,
			    "spuId": 26,
			    "imgName": "rBHu8l6UcKyAfzDsAAAPN5YrVxw870.jpg",
			    "imgUrl": "http://47.93.148.192:8080/xxx.jpg",
				 "name": "rBHu8l6UcKyAfzDsAAAPN5YrVxw870.jpg",
				 "url":  "http://47.93.148.192:8080/xxx.jpg"
			}
		新上传的图片文件对象的结构
			{
				name: "e814ec6fd86c5a8c.jpg"
				response: {
					data: "http://182.92.128.115:8080/group1/xxx.jpg"
				}
				url: "blob:http://localhost:9529/a5199d82-0811-442d-9ec2-dafae83d9ed9"
			}
		提交保存/更新SPU请求的图片对象的结构(目标):
			 {
			    "imgName": "下载 (1).jpg",
			    "imgUrl": "http://47.93.148.192:8080/xxx.jpg"
			 }
      */
  spuInfo.spuImageList = spuInfo.spuImageList.map((item) => ({
    imgName: item.name as string,
    imgUrl: item.response ? item.response.data : item.imgUrl,
  }));

  /*
    处理: 删除没有属性值的属性对象, 删除属性对象中的edit和valueName属性
    对spuInfo.spuSaleAttrList进行过滤(spuSaleAttrValueList是空数组)
    */
  spuInfo.spuSaleAttrList = spuInfo.spuSaleAttrList.filter((item) => {
    if (item.spuSaleAttrValueList.length > 0) {
      delete item.isShowEdit;
      return true;
    }
    return false;
  });

  // 如果一个spu的销售属性都没有了, 不发请求并提示
  if (spuInfo.spuSaleAttrList.length === 0) {
    ElMessage.warning("必须SPU销售属性!");
    return;
  }

  // 添加三级分类ID属性
  spuInfo.category3Id = categoryStore.getCategory3Id;

  // 发保存/更新spuInfo的请求
  await addOrUpdateSpuApi(spuInfo);

  // 请求成功后, 做后续的响应处理
  ElMessage.success("保存成功!");
  // 重置/清除数据
  emits("setShowStatus", ShowStatus.SPU_LIST);
};
</script>

<style></style>
